package com.uw.tookit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.uw.tookit.MyLocation.LocationResult;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

/**
 * Display the map (integrated with Google map).
 * By default, map will center around Red Square; 
 * if directed from result page, will mark all results on the map and center around the first result (closest to the current location);
 * if directed from info page, will center around the corresponding location.
 * Support getting current location.
 * 
 */
public class CampusMap extends MapActivity{
	MapView mapView;
	MapController mc;
	MyLocation myLocation = new MyLocation();
	AlertDialog alertDialog; // Alert user when gps timeout
	private ArrayList<ResultPageData> dataHolder = new ArrayList<ResultPageData>(); //holds the search results
	private boolean getCurLocFlag = false;
	private boolean hasLocation = false;
	private double fromLat;
    private double fromLon;
	
	/**
	 * Called when the activity is first created.
	 * Implements google map.
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		// displays the google map
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.map);
	    
	    // allows the map to zoom-in and zoom-out
	    mapView = (MapView) findViewById(R.id.mapView);
	    mapView.setBuiltInZoomControls(true);
	    
        mc = mapView.getController();
        GeoPoint center = null;
        int zoomLevel = 0;
        
        // check if any extras exist
        Bundle extras = getIntent().getExtras();
		if(extras != null) {
    		dataHolder = extras.getParcelableArrayList("results");
    		double lat = extras.getDouble("lat");
    		double lon = extras.getDouble("lon");
    		
    		List<Overlay> listOfOverlays = mapView.getOverlays();
    		
    		// Directed from results page "View all on map" button;
    		// Display all location on the map;
    		// Assume results size > 0.
    		if(dataHolder != null) {

    			Map<GeoPoint, String> places = new HashMap<GeoPoint, String>();
    			
	    		for(int i = 0; i < dataHolder.size(); i++) {
	    			ResultPageData r = dataHolder.get(i);
	    			String name = r.getResultName();
	    			GeoPoint g = new GeoPoint((int) (r.getLatitude() * 1E6), (int) (r.getLongitude() * 1E6));
	    			if(places.containsKey(g)){
	    				String newName = places.get(g);
	    				name = name + ", " + newName;
	    			}
	    			places.put(g, name);
	    			
	    		}
	    		for(GeoPoint g: places.keySet()){
	    			String name = places.get(g);
	    			PinOverlay mo = new PinOverlay(CampusMap.this, g, R.drawable.pushpin, name);
	    			listOfOverlays.add(mo);
	    		}
    			center = new GeoPoint((int) (dataHolder.get(0).getLatitude() * 1E6), (int) (dataHolder.get(0).getLongitude() * 1E6));
    		} else {
    			// Directed from info page "Map" button;
    			// Display that specific location on the map;
    			String name = extras.getString("name");
    			GeoPoint g = new GeoPoint((int) (lat * 1E6), (int) (lon * 1E6));
    			PinOverlay mo = new PinOverlay(CampusMap.this, g, R.drawable.pushpin, name);
		        listOfOverlays.add(mo);
		        center = g;
    		}
    	} else {
    		// No extras exist;
    		// Directed from main page;
    		// Default center is Red Square
			String coordinates[] = {"47.655965", "-122.309529"};
	        double lat = Double.parseDouble(coordinates[0]);
	        double lng = Double.parseDouble(coordinates[1]);	 
	        center = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
    	}
		zoomLevel = 18;
		mc.animateTo(center);
        mc.setZoom(zoomLevel);
        mapView.invalidate();
	}
	
	LocationResult locationResult = new LocationResult(){
		@Override
	    public void gotLocation(final Location loc){
	    	if(loc != null) {
		    	// Get the current location.
	        	fromLat = loc.getLatitude();
	        	fromLon = loc.getLongitude();
	        	hasLocation = true;
	    	}
	    }
	};
	
	/**
	 * Does not display any route on the map.
	 */
	@Override
	protected boolean isRouteDisplayed() {
	    return false;
	}
	
    /**
     * Create the options menu when load the map.
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mapmenu, menu);
        return true;
    }
    
    /**
     * Handle the event when a menu item is selected.
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
            case R.id.gps_button:
            	// if GPS service disabled on phone, notify user.
                if(!myLocation.getLocation(this, locationResult)) {
                	alertDialog = new AlertDialog.Builder(CampusMap.this).create();
		            alertDialog.setMessage("GPS and network services are not enabled on your phone. Enable them and try again.");
		      	  	alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
		      	  		public void onClick(DialogInterface dialog, int which) {
		      	  			return;
		      	    } });
	        	  alertDialog.show();
                } else {
                	int count = 0;
	            	// try to find current location;
	            	// timeout in 5 seconds.
	                while(!hasLocation && count <= 10){
	                	try {
							Thread.sleep(500); // sleep for 0.5 sec
						} catch (InterruptedException e) {
						}
	                	count++;
	                }
	                // If timeout, alert the user.
	                if(!hasLocation) {
	                	Handler mHandler = new Handler(Looper.getMainLooper());
	                	mHandler.post(new Runnable() {
	                		public void run() {
	                			AlertDialog alertDialog = new AlertDialog.Builder(CampusMap.this).create();
	                			alertDialog.setMessage("We can't find you right now. Try again later.");
	                			alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
	                				public void onClick(DialogInterface dialog, int which) {return;} 
	                			});
	                			alertDialog.show();
	                		}});
	                } else {
	                	// If current location found, mark it on the map.
	                	GeoPoint p = new GeoPoint((int) (fromLat * 1E6), (int) (fromLon * 1E6));
					    mc.animateTo(p);
					    
				        //---Add a location marker---
				        PinOverlay mo = new PinOverlay(CampusMap.this, p, R.drawable.pawpin, "You are here");
				        List<Overlay> listOfOverlays = mapView.getOverlays();
				        if(getCurLocFlag)
				        	listOfOverlays.remove(listOfOverlays.size()-1);
				        listOfOverlays.add(mo);
				        getCurLocFlag = true;
				        mc.setZoom(18);
				        mapView.invalidate();
	                }
                }
                return true;
            case R.id.mainpage_button:
            	Intent resultsPage = new Intent(CampusMap.this, UWToolkitActivity.class);
                startActivityForResult(resultsPage, 0);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    
    /**
     * Display the category list when get directions button is pressed.
     */
    public void showPath() {
    	Intent resultsPage = new Intent(CampusMap.this, GetPath.class);  
        startActivityForResult(resultsPage, 0);
    }
	
    /**
     * Called when the activity will start interacting with the user.
     */
	@Override
	public void onResume(){
		super.onResume();
	}
	
	/**
	 * Called when the system is about to start resuming a previous activity. 
	 */
	@Override
	public void onPause(){
		super.onPause();
		if(myLocation != null)
			myLocation.cancelTimer();
	}
	
	/**
	 * The final call you receive before your activity is destroyed.
	 */
	@Override
	  public void onDestroy() {
	    super.onDestroy();
	}
}

